CircleDecal.shader 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. Shader "FlatKit/Demos/Circle Decal"
  2. {
  3. Properties
  4. {
  5. [MainColor][HDR]_Color("_Color (default = 1,1,1,1)", Color) = (1,1,1,1)
  6. [Space]
  7. [Enum(UnityEngine.Rendering.BlendMode)]_DecalSrcBlend("Src Blend", Int) = 5 // 5 = SrcAlpha
  8. [Enum(UnityEngine.Rendering.BlendMode)]_DecalDstBlend("Dst Blend", Int) = 10 // 10 = OneMinusSrcAlpha
  9. [Space]
  10. [Toggle(_ProjectionAngleDiscardEnable)] _ProjectionAngleDiscardEnable("Angle Discard Enable", float) = 0
  11. _ProjectionAngleDiscardThreshold(" Threshold", range(-1,1)) = 0
  12. [Space]
  13. _StencilRef("Stencil Reference", Float) = 0
  14. [Enum(UnityEngine.Rendering.CompareFunction)]_StencilComp("Stencil Compare", Float) = 0 //0 = disable
  15. [Space]
  16. [Enum(UnityEngine.Rendering.CompareFunction)]_ZTest("Depth Test", Float) = 0 //0 = disable
  17. [Space]
  18. [Enum(UnityEngine.Rendering.CullMode)]_Cull("Cull", Float) = 1 //1 = Front
  19. }
  20. SubShader
  21. {
  22. Tags
  23. {
  24. "RenderType" = "Overlay" "Queue" = "Transparent-499" "DisableBatching" = "True"
  25. }
  26. Pass
  27. {
  28. Stencil
  29. {
  30. Ref[_StencilRef]
  31. Comp[_StencilComp]
  32. }
  33. Cull[_Cull]
  34. ZTest[_ZTest]
  35. ZWrite off
  36. Blend[_DecalSrcBlend][_DecalDstBlend]
  37. HLSLPROGRAM
  38. #pragma vertex vert
  39. #pragma fragment frag
  40. // make fog work
  41. #pragma multi_compile_fog
  42. // due to using ddx() & ddy()
  43. #pragma target 3.0
  44. #pragma shader_feature_local_fragment _ProjectionAngleDiscardEnable
  45. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  46. struct appdata {
  47. float3 positionOS : POSITION;
  48. };
  49. struct v2f {
  50. float4 positionCS : SV_POSITION;
  51. float4 screenPos : TEXCOORD0;
  52. float4 viewRayOS : TEXCOORD1; // xyz: viewRayOS, w: extra copy of positionVS.z
  53. float4 cameraPosOSAndFogFactor : TEXCOORD2;
  54. };
  55. sampler2D _MainTex;
  56. sampler2D _CameraDepthTexture;
  57. CBUFFER_START(UnityPerMaterial)
  58. float4 _MainTex_ST;
  59. float _ProjectionAngleDiscardThreshold;
  60. half4 _Color;
  61. half2 _AlphaRemap;
  62. half _MulAlphaToRGB;
  63. CBUFFER_END
  64. v2f vert(appdata input) {
  65. v2f o;
  66. VertexPositionInputs vertexPositionInput = GetVertexPositionInputs(input.positionOS);
  67. o.positionCS = vertexPositionInput.positionCS;
  68. #if _UnityFogEnable
  69. o.cameraPosOSAndFogFactor.a = ComputeFogFactor(o.positionCS.z);
  70. #else
  71. o.cameraPosOSAndFogFactor.a = 0;
  72. #endif
  73. o.screenPos = ComputeScreenPos(o.positionCS);
  74. float3 viewRay = vertexPositionInput.positionVS;
  75. o.viewRayOS.w = viewRay.z;
  76. viewRay *= -1;
  77. float4x4 ViewToObjectMatrix = mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V);
  78. o.viewRayOS.xyz = mul((float3x3)ViewToObjectMatrix, viewRay);
  79. o.cameraPosOSAndFogFactor.xyz = mul(ViewToObjectMatrix, float4(0, 0, 0, 1)).xyz;
  80. return o;
  81. }
  82. // copied from URP12.1.2's ShaderVariablesFunctions.hlsl
  83. #if SHADER_LIBRARY_VERSION_MAJOR < 12
  84. float LinearDepthToEyeDepth(float rawDepth)
  85. {
  86. #if UNITY_REVERSED_Z
  87. return _ProjectionParams.z - (_ProjectionParams.z - _ProjectionParams.y) * rawDepth;
  88. #else
  89. return _ProjectionParams.y + (_ProjectionParams.z - _ProjectionParams.y) * rawDepth;
  90. #endif
  91. }
  92. #endif
  93. half4 frag(v2f i) : SV_Target {
  94. i.viewRayOS.xyz /= i.viewRayOS.w;
  95. float2 screenSpaceUV = i.screenPos.xy / i.screenPos.w;
  96. float sceneRawDepth = tex2D(_CameraDepthTexture, screenSpaceUV).r;
  97. float3 decalSpaceScenePos;
  98. if (unity_OrthoParams.w) {
  99. float sceneDepthVS = LinearDepthToEyeDepth(sceneRawDepth);
  100. float2 viewRayEndPosVS_xy = float2(
  101. unity_OrthoParams.xy * (i.screenPos.xy - 0.5) * 2 /* to clip space */);
  102. float4 vposOrtho = float4(viewRayEndPosVS_xy, -sceneDepthVS, 1); // view space pos
  103. float3 wposOrtho = mul(UNITY_MATRIX_I_V, vposOrtho).xyz; // view space to world space
  104. decalSpaceScenePos = mul(GetWorldToObjectMatrix(), float4(wposOrtho, 1)).xyz;
  105. } else {
  106. float sceneDepthVS = LinearEyeDepth(sceneRawDepth, _ZBufferParams);
  107. decalSpaceScenePos = i.cameraPosOSAndFogFactor.xyz + i.viewRayOS.xyz * sceneDepthVS;
  108. }
  109. float2 decalSpaceUV = decalSpaceScenePos.xy + 0.5;
  110. float shouldClip = 0;
  111. #if _ProjectionAngleDiscardEnable
  112. float3 decalSpaceHardNormal = normalize(cross(ddx(decalSpaceScenePos), ddy(decalSpaceScenePos)));
  113. shouldClip = decalSpaceHardNormal.z > _ProjectionAngleDiscardThreshold ? 0 : 1;
  114. #endif
  115. clip(0.5 - abs(decalSpaceScenePos) - shouldClip);
  116. float4 col = 1;
  117. col.a = smoothstep(0, 0.01, 1 - length(decalSpaceUV - 0.5) * 2);
  118. col *= _Color;
  119. col.rgb = MixFog(col.rgb, i.cameraPosOSAndFogFactor.a);
  120. return col;
  121. }
  122. ENDHLSL
  123. }
  124. }
  125. }